package com.tim.framework.dao.impl;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.sql.SQLException;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.tim.framework.common.PageProperty;
import com.tim.framework.dao.EntityDao;
import com.tim.framework.util.CommonTools;

/**
 * 
 * @author kim *
 * @see EntityDao
 */
@SuppressWarnings("unchecked")
abstract public class EntityDaoImpl<T> extends HibernateDaoSupport implements
		EntityDao<T> {
	Class<T> poClass = (Class<T>) ((ParameterizedType) getClass()
			.getGenericSuperclass()).getActualTypeArguments()[0];;

	public T getById(Serializable id) {
		return (T) getHibernateTemplate().get(poClass, id);
	}

	public Serializable create(T po) {
		try {
			return getHibernateTemplate().save(po);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	public void update(T po) {
		getHibernateTemplate().update(po);
	}

	public void delete(T po) {
		getHibernateTemplate().delete(po);
	}

	public List<T> findAll() {
		return (List<T>) getHibernateTemplate().find(
				"from " + poClass.getName());

	}

	public int findAllCount() {
		return findCount(new PageProperty());
	}

	public int findCount(final PageProperty pp) {
		return (Integer) getHibernateTemplate().execute(
				new HibernateCallback() {
					public Object doInHibernate(Session session)
							throws HibernateException, SQLException {
						String sql = "select count(*) from "
								+ poClass.getName()
								+ CommonTools.makeSqlWhereOrder(pp
										.getSearchString(), "");
						Query query = session.createQuery(sql);
						CommonTools.setParameterList(query, pp);
						return query.uniqueResult();
					}
				});
	}

	public List<T> findPageList(final PageProperty pp) {
		return (List<T>) getHibernateTemplate().execute(
				new HibernateCallback() {
					public Object doInHibernate(Session session)
							throws HibernateException, SQLException {
						String sql = "from "
								+ poClass.getName()
								+ CommonTools
										.makeSqlWhereOrder(
												pp.getSearchString(), pp
														.getOrderString());
						Query query = session.createQuery(sql);
						query.setFirstResult(pp.getNfirstindex());
						if (pp.getNpagesize() > 0) {
							query.setMaxResults(pp.getNpagesize());
						}
						CommonTools.setParameterList(query, pp);
						List list = query.list();
						return list;
					}
				});
	}

	/**
	 * 执行update或delete的hql语句.
	 * 
	 * @param String
	 *            执行语句的模式update或delete
	 * @param String
	 *            update或delete之后的sql语句
	 * @param List
	 *            执行参数
	 * @return Integer 影响的行数.
	 */
	public Integer executeUpdate(final String model, final String sql,
			final List params) {
		return (Integer) this.getHibernateTemplate().execute(
				new HibernateCallback() {
					public Object doInHibernate(Session session)
							throws HibernateException, SQLException {
						StringBuilder str = new StringBuilder();
						str.append(model + " " + poClass.getName() + " ");
						str.append(sql);
						Query query = session.createQuery(str.toString());
						for (int i = 0; i < params.size(); i++) {
							query.setParameter(i, params.get(i));
						}
						return query.executeUpdate();
					}
				});
	}

	/**
	 * 执行hql查询语句.
	 */
	public List<Object> executeHqlQuery(final String sql, final List<Object> params) {
		return (List<Object>)this.getHibernateTemplate().execute(new HibernateCallback() {
			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				Query query = session.createQuery(sql);
				for (int i = 0; i < params.size(); i++) {
					query.setParameter(i, params.get(i));
				}
				return query.list();
			}
		});
	}
}